<?php

namespace App\Http\Controllers\Api;

use App\GameChannel\SdkBase;
use App\Http\Controllers\Controller;
use App\Jobs\UserLoginQueue;
use App\Jobs\UserRegQueue;
use App\Models\Channels;
use App\Models\Games;
use App\Models\Log\LogLogin;
use App\Models\UserLogin;
use App\Models\Users;
use App\Services\GameChannelService;
use App\Services\GameHtService;
use App\Services\LoginService;
use App\Services\SdkService;
use App\Services\UserHutongService;
use App\Services\WanSdk\WanSdkService;
use Illuminate\Http\Request;
use YQ\YqExtend;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        $params = $request->all();

        // 校验签名
        $ret = SdkService::getInstance()->checkSign($params);
        if ($ret === false) {
            return yqerr(101);
        }

        $game_id         = $params['game_id'];
        $channel         = $params['channel'];
        $package_id      = $params['package_id'] ?? 0;
        $game_channel_id = $params['game_channel_id'] ?? 0;
        $game_channel_id = GameChannelService::getInstance()->checkAndGetId($game_id, $channel, $game_channel_id);
        $env_type        = WanSdkService::getInstance()->getEnvType($params);

        // 校验登录
        $can_login = LoginService::getInstance()->canLogin($game_id, $game_channel_id);
        if (!$can_login) {
            return yqerr(6001);
        }

        // 渠道处理对象
        $sdkobj = SdkBase::loadSDK($game_id, $channel, $game_channel_id);
        if (!$sdkobj) {
            return yqerr(6002);
        }

        $notify = $sdkobj->login($request);
        if ($notify->errno !== 0) {
            return yqerr($notify->errno);
        }

        // 微信小游戏
        // 是先登录后激活的，所以此处将小游戏的openid当做唯一设备码
        if ($channel == Channels::CHANNEL_WXGAME && empty($params['device_num'])) {
            $params['device_num'] = $notify->openid;
        }

        $now = time();
        $is_reg = 0;
        $ip = YqExtend::getIP();
        $openid = $notify->openid;

        $hutong = UserHutongService::getInstance()->getByChannelOpenid($game_id, $channel, $openid);
        if ($hutong) {
            $user = Users::find($hutong->user_id);
        } else {
            $user = Users::whereRaw("channel_openid='{$openid}' AND game_id={$game_id} AND channel={$channel}")->first();
        }

        if (!$user) {
            $user                   = new Users;
            $user->create_time      = $now;
            $user->game_id          = $game_id;
            $user->channel          = $channel;
            $user->game_channel_id  = $game_channel_id;
            $user->package_id       = $package_id;
            $user->ip               = $ip;
            $user->channel_openid   = $openid;
            $user->channel_nickname = $notify->nickname;
            $user->channel_openid2  = $notify->openid2;
            $user->env_type         = $env_type;

            SdkService::getInstance()->supplementDevice($user, $params);
            $user->save();

            // 队列执行注册账号后的一系列事件
            UserRegQueue::dispatch($user->user_id)->onQueue('default');

            $is_reg = 1;
        }

        if (!empty($notify->openid2) && empty($user->channel_openid2)) {
            $user->channel_openid2 = $notify->openid2;
            $user->save();
        }

        // 登录票据
        $user_login = UserLogin::whereRaw("user_id={$user->user_id}")->first();
        if (!$user_login) {
            $user_login = new UserLogin;
            $user_login->create_time = $now;
            $user_login->game_id = $game_id;
            $user_login->channel = $channel;
            $user_login->user_id = $user->user_id;
        }

        $user_login->token = YqExtend::uniqid32();
        $user_login->login_time = $now;
        $user_login->login_ip   = $ip;
        $user_login->save();

        // 添加登录日志
        $log_login              = new LogLogin;
        $log_login->package_id  = $package_id;
        $log_login->game_id     = $game_id;
        $log_login->channel     = $channel;
        $log_login->user_id     = $user->user_id;
        $log_login->token       = $user_login->token;
        $log_login->create_time = $now;
        $log_login->ip          = $ip;
        SdkService::getInstance()->supplementDevice($log_login, $params);
        $log_login->save();

        // 队列执行登录后的一系列事件
        UserLoginQueue::dispatch($log_login->getSuffix(), $log_login->id, $params)->onQueue('default');

        // 返回登录数据给前端
        $out = [
            'token'            => $user_login->token,
            'user_id'          => $user->user_id,
            'channel'          => $channel,
            'channel_openid'   => $openid,
            'time'             => $now,
        ];
        $game = Games::where('game_id', $game_id)->first();
        $out['sign']            = SdkService::getInstance()->createCpLoginSign($game->appkey, $out);
        $out['is_reg']          = $is_reg;
        $out['game_channel_id'] = $game_channel_id;
        $out['toapk_time']      = $user->toapk_time ?? 0;
        $out['env_type']        = $env_type;

        return yqok($out);
    }
}
